GKE(Google Kubernetes Engine)クラスタにアプリをデプロイする
こんにちは、yagiです。
今回は、Cloud Shell を起動して、Google Cloud の GKE(Google Kubernetes Engine)クラスタにアプリをデプロイする手順について記載します。
Cloud Shell 、とっても便利で使いやすい!
Kubernetes とは
Kubernetes は、コンテナー化されたアプリケーションを必要な場所でいつでも実行できるようにし、動作に必要なリソースとツールを見つけるのに役立ちます。Kubernetes は、コンテナ オーケストレーションにおける Google の蓄積された経験と、コミュニティからの最善のアイデアを組み合わせて設計された、本番環境に対応したオープン ソース プラットフォームです。
Pod と Service と Ingress(ざっくり)
Pod は、ホスト上で実行できるコンテナーのコレクションです。1つのPodに複数のコンテナを稼働することができます。Pod は Kubernetes の最小単位と定義されています。
Service は、デプロイしたPod をクラスター外部へ公開するためのリソースとなります。複数の Pod に対し、ロードバランサーなどを利用して、単一のDNS名でアクセス可能となり、正常稼働している Pod のみにアクセスできるようになります。
Service の手前に Ingress を置くと、Ingressは、クラスターの外部からクラスター内のサービスにHTTP および HTTPS ルートを公開 します。トラフィック ルーティングは、Ingress リソースで定義されたルールによって制御されます。
以下のイメージとなります。
What is Ingress?より引用
やってみる
プロジェクトセレクタでプロジェクトを選択し、Artifact Registry and Google Kubernetes Engine API を有効にします。
Cloud Shell を起動する
コンソールからCloud Shell を起動します。
しかも、鉛筆マークを押下すると、エディタ を開くことができます。これがすごく便利!
GKE クラスタを作成する
hello-cluster という名前の Autopilot クラスタを作成します。
$ gcloud container clusters create-auto hello-cluster --region=us-west1 Note: The Pod address range limits the maximum size of the cluster. Please refer to https://cloud.google.com/kubernetes-engine/docs/how-to/flexible-pod-cidr to learn how to optimize IP address allocation. Creating cluster hello-cluster in us-west1... Cluster is being health-checked...done. Created [https://container.googleapis.com/v1/projects/XXXX/zones/us-west1/clusters/hello-cluster]. To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-west1/hello-cluster?project=XXXX kubeconfig entry generated for hello-cluster. NAME: hello-cluster LOCATION: us-west1 MASTER_VERSION: 1.24.8-gke.2000 MASTER_IP: 35.233.164.192 MACHINE_TYPE: e2-medium NODE_VERSION: 1.24.8-gke.2000 NUM_NODES: 3 STATUS: RUNNING
クラスタの認証情報を取得する
$ gcloud container clusters get-credentials hello-cluster --region us-west1 Fetching cluster endpoint and auth data. kubeconfig entry generated for hello-cluster.
このコマンドにより、作成したクラスタを使用するように kubectl が構成されます。
アプリケーションをクラスタにデプロイする
Deployment を作成、公開します。
$ kubectl create deployment hello-server \ --image=us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 deployment.apps/hello-server created
$ kubectl expose deployment hello-server --type LoadBalancer --port 80 --target-port 8080 service/hello-server exposed
--type LoadBalancer で、コンテナに Compute Engine ロードバランサが作成されます。インターネット用に公開ポート 80が初期化され、アプリケーションのポート 8080 にトラフィックがルーティングされます。
アプリケーションを検査して表示する
実行中の Pod を検査します。
$ kubectl get pods NAME READY STATUS RESTARTS AGE hello-server-7cc77d5467-vqv5x 1/1 Running 0 4m49s
クラスタで 1 つの hello-server Pod が実行されていることが確認できます。
Service を検査するには、kubectl get service を使用します。
$ kubectl get service hello-server NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-server LoadBalancer 10.104.2.137 35.197.80.73 80:30874/TCP 6m13s
外部 IP アドレスと公開ポートを指定して、ウェブブラウザでアプリケーションを表示します。
なお、デプロイしたhello-app は、以下の 2 つのファイル(main.go と Dockerfile)で構成されるシンプルなウェブサーバー アプリケーションとなっています。
main.go
package main import ( "fmt" "log" "net/http" "os" ) func main() { // register hello function to handle all requests mux := http.NewServeMux() mux.HandleFunc("/", hello) // use PORT environment variable, or default to 8080 port := os.Getenv("PORT") if port == "" { port = "8080" } // start the web server on port and accept requests log.Printf("Server listening on port %s", port) log.Fatal(http.ListenAndServe(":"+port, mux)) } // hello responds to the request with a plain-text "Hello, world" message. func hello(w http.ResponseWriter, r *http.Request) { log.Printf("Serving request: %s", r.URL.Path) host, _ := os.Hostname() fmt.Fprintf(w, "Hello, world!\n") fmt.Fprintf(w, "Version: 1.0.0\n") fmt.Fprintf(w, "Hostname: %s\n", host) }
Dockerfile
# Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. FROM golang:1.19.2 as builder WORKDIR /app RUN go mod init hello-app COPY *.go ./ RUN CGO_ENABLED=0 GOOS=linux go build -o /hello-app FROM gcr.io/distroless/base-debian11 WORKDIR / COPY --from=builder /hello-app /hello-app ENV PORT 8080 USER nonroot:nonroot CMD ["/hello-app"]
感想
単一のPod と Service のみのシンプルなGKEクラスタにアプリをデプロイして公開する手順を、Cloud Shellを起動して実施してみました。
次回はIngress を使用したルール制御や、複数サービスへのfanout構成なども試してみたいなと思います。